
from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponse

from planet.models import PlanetInfo, Planet
from fleet.models import StaticFleet, MovingFleet
from player.models import OCBPlayer
from planet.forms import PlanetSearch
from constants import AGRO, MINERO, TECHNO, FARMS, X_MIN, X_MAX, Y_MIN, Y_MAX, REMOVED_SYSTEMS, ADDED_SYSTEMS, SC


def defense_map(request):
    planets = Planet.objects.filter(sc=SC, x__gte = X_MIN, y__gte = Y_MIN, x__lte = X_MAX, y__lte = Y_MAX).order_by('x','-y')
    for system in REMOVED_SYSTEMS:
        planets = planets.exclude(x = system[0], y = system[1])
    for system in ADDED_SYSTEMS:
        planets = planets|Planet.objects.filter(x=system[0],y=system[1])
    #planets = [ocbp.planet for ocbp in PlanetInfo.objects.all().order_by('planet__x','-planet__y')]
    min_x, max_x, min_y, max_y = _get_min_max_coords(list(planets))
    planets = _sort_planets_in_table(planets,min_x, max_x, min_y, max_y)
    
    xcoords = range(min_x,max_x+1)
    
    return render(request,'planet/defense_map.html',{
                                                                'xcoords':xcoords,
                                                                'min_y':min_y,
                                                                'planets':planets})
    
def farms(request,area=None):
    coords = FARMS[area]
    planets = list(Planet.objects.filter(x__gte = coords[0], y__gte = coords[1], x__lte = coords[2], y__lte = coords[3]).order_by('x','-y'))
    planets = _sort_planets_in_table(planets,coords[0], coords[2], coords[1], coords[3])
    xcoords = range(coords[0],coords[2]+1)
    return render(request,'planet/defense_map.html',{
                                                                'xcoords':xcoords,
                                                                'min_y':coords[1],
                                                                'planets':planets})

    
def planetsearch(request):
    
    #ocbplayer = OCBPlayer.objects.get(user=request.user)
    if request.method == "POST":
        form = PlanetSearch(data=request.POST)
        if form.is_valid() :
            x_min,y_min,x_max,y_max = (int(request.POST['x_min']),int(request.POST['y_min']),int(request.POST['x_max']),int(request.POST['y_max']))
            planets = Planet.objects.filter(x__gte=x_min, x__lte=x_max, y__gte=y_min, y__lte=y_max)
            if 'notag' in request.POST.keys():
                planets = planets.filter(ally=None)
            if 'agro' not in request.POST.keys():
                planets = planets.exclude(prod_type=AGRO)
            if 'techno' not in request.POST.keys():
                planets = planets.exclude(prod_type=TECHNO)
            if 'minero' not in request.POST.keys():
                planets = planets.exclude(prod_type=MINERO)
            
            return render(request,'planet/planetsearch.html',{'form':form,'planets':planets})
        else:
            return render(request,'planet/planetsearch.html',{'form':form,'error':form.errors})
    else :
        form = PlanetSearch()
        return render(request,'planet/planetsearch.html',{'form':form})

def getfleetinfo(request,planet_name=None):
    
    try :
        planet = Planet.objects.get(name=planet_name)
        planetinfo = planet.planetinfo_set.all()[0]
        fleets = StaticFleet.objects.filter(planet=planet)
        moving_fleets = MovingFleet.objects.filter(planet_destination=planet).order_by('arrival_time')
        if planetinfo.planet_owner :
            owner = planetinfo.planet_owner.player.nickname
        elif planetinfo.is_neutral :
            owner = "Neutral"
        else :
            owner = "?????"
            
        view = False
        if  planetinfo.planet.get_color() == "safe":
            if owner == "Neutral" :
                if request.user.ocbplayer_set.all()[0] not in planetinfo.planet_survey.all() :
                    view = False
                else :
                    view = True
            elif request.user == planetinfo.planet_owner.user :
                view = True
            else :
                view = False
        else :
            view = True

        if view :
            total_attacking_fleet = 0
            total_defending_fleet = 0
            total_attacking_armies = 0
            total_defending_armies = 0
            total_moving_fleets = 0
            total_moving_armies = 0
            attacker_list = []
            defender_list = []
            
            html_response = "<br/><br/>\n<center>\nStatus on planet <b>%s</b>, owner : <b>%s</b><br/>"%(planet_name,owner)
            html_response += "<table><tr><td width=\"100px\">"
            
            if planetinfo.stasis == 1:
                html_response += "<span style=\"bgcolor:#333333;color:#9988ff\"><b>Stasis</b></span></td>"
            elif planetinfo.stasis == 2:
                html_response += "<span style=\"bgcolor:#333333;color:red\"><b>Stasis OFF</b></span></td>"
            else :
                html_response += "<span style=\"bgcolor:#333333;color:#9988ff\"><b>??????</b></span></td>"
            if planetinfo.energy:
                html_response += "</td><td width=\"100px\">Energy : <span style=\"color:#aaaa77;\"><b>"+str(planetinfo.energy)+"</b></span>/"+str(planetinfo.max_energy)+"</td><td width=\"100px\"></td></tr>"
            else :
                html_response += "</td><td width=\"100px\">Energy : <span style=\"color:#aaaa77;\">??</span>/??</td><td width=\"100px\"></td></tr>"
            for f in fleets :
                if f.defending :
                    if f.amount_fleet:
                        total_defending_fleet += f.amount_fleet
                    if f.amount_GA :
                        total_defending_armies += f.amount_GA
                    if f.owner not in defender_list:
                        defender_list.append(f.owner)
                else :
                    if f.amount_fleet:
                        total_attacking_fleet += f.amount_fleet
                    if f.amount_GA :
                        total_attacking_armies += f.amount_GA
                    if f.owner not in attacker_list:
                        attacker_list.append(f.owner)
            html_response += "<tr><td></td><td>Defense</td><td>Attack</td></tr>"
            html_response += "<tr><td>Fleets</td><td>"+_get_formated(total_defending_fleet)+"</td><td>"+_get_formated(total_attacking_fleet)+"</td></tr>"
            html_response += "<tr><td>Armies</td><td>"+_get_formated(total_defending_armies)+"</td><td>"+_get_formated(total_attacking_armies)+"</td></tr>"
            html_response += "<tr><td>Players</td><td><br/>"
            for defender in defender_list :
                html_response += "%s<br/>"%defender
            html_response += "</td><td><br/>"
            for attacker in attacker_list :
                html_response += "%s<br/>"%attacker
            html_response += "</td></tr>"
            html_response += "</table><br/><br/>Last update info : %s<br /><br />\n<ul>"%planetinfo.last_update_date
            
            for f in moving_fleets :
                html_response += "<li>%s : %s/%s @%s (last update : %s)</li>"%(f.owner,_get_formated(f.amount_fleet),_get_formated(f.amount_GA),str(f.arrival_time),str(f.last_update_date))
            html_response += "</ul></center>"
        else :
            html_response = "<br/><br/>\n<center>Planet is safe, you don't need to view status</center>"
        return HttpResponse(html_response)
    except ObjectDoesNotExist :
        import traceback
        print traceback.format_exc()
        return HttpResponse("")
        
def _sort_planets_in_table(planets,min_x, max_x, min_y, max_y):
    sorted_planets = []
    
    for i in range(0,max_y-min_y+1):
        sorted_planets.append([])
        for j in range(0,max_x-min_x+1):
            sorted_planets[i].append([])
    for pl in planets:
        sorted_planets[abs(pl.y-max_y)][pl.x-min_x].append(pl)

    return sorted_planets
        
def _get_min_max_coords(planets):
    min_x = 1000000
    max_x = -1000000
    min_y = 1000000
    max_y = -1000000
    for p in planets:
        if p.x > max_x:
            max_x = p.x
        if p.x < min_x:
            min_x = p.x
        if p.y > max_y:
            max_y = p.y
        if p.y < min_y:
            min_y = p.y
    return [min_x, max_x, min_y, max_y]

def _get_formated(amount):
    if amount > 1000000000:
        return "%3.1f B"%(float(amount)/1000000000)
    elif amount > 1000000:
        return "%3.1f M"%(float(amount)/1000000)
    elif amount > 1000:
        return "%3.1f k"%(float(amount)/1000)
    else :
        return str(amount)
